Shader "Builtin-YoFi/VFX/BackBlur"
{
    Properties
	{
        _MaskTex("MaskTex", 2D) = "white" {}
        _MaskTexUSpeed("MaskTex U Speed", Range( -10 , 10)) = 0
		_MaskTexVSpeed("MaskTex V Speed", Range( -10 , 10)) = 0
        _Color("Main Color", Color) = (1,1,1,1)
	    [Toggle] _CustomData("Custom Data", float) = 0.0
        _Size("Blur Size", Range(0, 20)) = 1
	}
    
    SubShader
    {
        // Draw after all opaque geometry
        Tags { "Queue" = "Transparent" }
        ZWrite Off
        // Horizontal blur  
        GrabPass {
            Tags { "LightMode" = "Always" }
        }
        Pass {
            Tags { "LightMode" = "Always" }
            Blend SrcAlpha OneMinusSrcAlpha
            Name "BackBlurHor"
            CGPROGRAM
            #pragma vertex vert  
            #pragma fragment frag  
            #include "UnityCG.cginc"
            
            sampler2D _GrabTexture;
            float4 _GrabTexture_TexelSize;
            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _Size;
            uniform float4 _Color;

            half4 _MaskTex_ST;
            sampler2D _MaskTex;
            half _CustomData;
            half _MaskTexUSpeed;
			half _MaskTexVSpeed;

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord : TEXCOORD0;
                float4 texcoord1 : TEXCOORD1;
                float4 color    : COLOR;
            };

            struct v2f {
                float4 vertex : POSITION;
                float4 uvgrab : TEXCOORD0;
                float2 uv_MaskTex : TEXCOORD1;
                float blurSize : TEXCOORD2;
                float4 color    : COLOR;
            };

            v2f vert(appdata_t v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                #if UNITY_UV_STARTS_AT_TOP  
                float scale = -1.0;
                #else  
                float scale = 1.0;
                #endif  
                o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
                o.uvgrab.zw = o.vertex.zw;
                
                float4 customData1 = v.texcoord1;
                float2 uv_MaskTex = v.texcoord * _MaskTex_ST.xy + _MaskTex_ST.zw;
				uv_MaskTex = _CustomData ? uv_MaskTex + customData1.xy : uv_MaskTex;
                float2 uv_MaskTex_Speed = float2(_MaskTexUSpeed,_MaskTexVSpeed);
				float2 uv_MaskTex_offset = uv_MaskTex  - frac(uv_MaskTex_Speed * _Time.y *0.25);
                
				float blurSize = _CustomData ? _Size * customData1.z : _Size;
                o.uv_MaskTex = uv_MaskTex_offset;
                o.blurSize = blurSize;
                

                o.color = v.color;
                return o;
            }


            


            half4 GrabPixel(v2f i, float weight, float kernelx) {
                if (i.uvgrab.x == 0 && i.uvgrab.y == 0) {
                    kernelx = 0;
                }
                return tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x*kernelx*i.blurSize, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight;
            }
            half4 frag(v2f i) : COLOR {
                half4 sum = half4(0,0,0,0);
                // #define GRABPIXEL(weight, kernelx) tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x + _GrabTexture_TexelSize.x * kernelx*_Size, i.uvgrab.y, i.uvgrab.z, i.uvgrab.w))) * weight
				float4 maskTex = tex2D(_MaskTex,i.uv_MaskTex);

                
                sum += GrabPixel(i, 0.05, -4.0);
                sum += GrabPixel(i, 0.09, -3.0);
                sum += GrabPixel(i, 0.12, -2.0);
                sum += GrabPixel(i, 0.15, -1.0);
                sum += GrabPixel(i, 0.18,  0.0);
                sum += GrabPixel(i, 0.15, +1.0);
                sum += GrabPixel(i, 0.12, +2.0);
                sum += GrabPixel(i, 0.09, +3.0);
                sum += GrabPixel(i, 0.05, +4.0);

                float4 col5 = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
                float decayFactor = 1.0f;
                if (i.uvgrab.x == 0 && i.uvgrab.y == 0) {
                    decayFactor = 0;
                }
                sum = lerp(col5, sum, decayFactor) * i.color * _Color;
                
                sum.a *= maskTex.r;
                return sum;
            }
            ENDCG
        }
        // Vertical blur  
        GrabPass {
            Tags { "LightMode" = "Always" }
        }
        Pass {
            Tags { "LightMode" = "Always" }
            Blend SrcAlpha OneMinusSrcAlpha
            Name "BackBlurVer"
            CGPROGRAM
            #pragma vertex vert  
            #pragma fragment frag  
            #include "UnityCG.cginc"
            
            sampler2D _GrabTexture;
            float4 _GrabTexture_TexelSize;
            float _Size;
            uniform float4 _Color;

            half4 _MaskTex_ST;
            sampler2D _MaskTex;
            half _CustomData;
            half _MaskTexUSpeed;
			half _MaskTexVSpeed;

            struct appdata_t {
                float4 vertex : POSITION;
                float2 texcoord: TEXCOORD0;
                float4 texcoord1 : TEXCOORD1;
                float4 color    : COLOR;
            };

            struct v2f {
                float4 vertex : POSITION;
                float4 uvgrab : TEXCOORD0;
                float2 uv_MaskTex : TEXCOORD1;
                float blurSize : TEXCOORD2;
                float4 color    : COLOR;
            };

            v2f vert(appdata_t v) {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                #if UNITY_UV_STARTS_AT_TOP  
                float scale = -1.0;
                #else  
                float scale = 1.0;
                #endif  
                o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
                o.uvgrab.zw = o.vertex.zw;

                float4 customData1 = v.texcoord1;
                float2 uv_MaskTex = v.texcoord * _MaskTex_ST.xy + _MaskTex_ST.zw;
				uv_MaskTex = _CustomData ? uv_MaskTex + customData1.xy : uv_MaskTex;
                float2 uv_MaskTex_Speed = float2(_MaskTexUSpeed,_MaskTexVSpeed);
				float2 uv_MaskTex_offset = uv_MaskTex  - frac(uv_MaskTex_Speed * _Time.y *0.25);
                
				float blurSize = _CustomData ? _Size * customData1.z : _Size;
                o.uv_MaskTex = uv_MaskTex_offset;
                o.blurSize = blurSize;

                o.color = v.color;
                return o;
            }


            
            half4 GrabPixel(v2f i, float weight, float kernely) {
                if (i.uvgrab.x == 0 && i.uvgrab.y == 0) {
                    kernely = 0;
                }
                return tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y*kernely*i.blurSize, i.uvgrab.z, i.uvgrab.w))) * weight;
            }

            half4 frag(v2f i) : COLOR {
                half4 sum = half4(0,0,0,0);
                // #define GRABPIXEL(weight,kernely) tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(float4(i.uvgrab.x, i.uvgrab.y + _GrabTexture_TexelSize.y * kernely*_Size, i.uvgrab.z, i.uvgrab.w))) * weight  


                float4 maskTex = tex2D(_MaskTex,i.uv_MaskTex);
                
                sum += GrabPixel(i, 0.05, -4.0);
                sum += GrabPixel(i, 0.09, -3.0);
                sum += GrabPixel(i, 0.12, -2.0);
                sum += GrabPixel(i, 0.15, -1.0);
                sum += GrabPixel(i, 0.18,  0.0);
                sum += GrabPixel(i, 0.15, +1.0);
                sum += GrabPixel(i, 0.12, +2.0);
                sum += GrabPixel(i, 0.09, +3.0);
                sum += GrabPixel(i, 0.05, +4.0);

                float4 col5 = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
                float decayFactor = 1.0f;
                if (i.uvgrab.x == 0 && i.uvgrab.y == 0) {
                    decayFactor = 0;
                }
                sum = lerp(col5, sum, decayFactor) * i.color * _Color;

                sum.a *= maskTex.r;
                return sum;
            }
            ENDCG
        }

    }
}